# -*- coding: utf-8 -*-
# !spider/Scripts/python.exe
import json
import os
import psutil
from multiprocessing import Process

from util.selenium import webdriver
from util.selenium.webdriver import ChromeOptions, DesiredCapabilities

import sys
from settings import base_path

sys.path.append(base_path)

from base.BaseMethod import BM
from util.DataQuery.DbTools import DbTools
from util.DataQuery.hzflowOperation import hzflowOperation
from util.Logger import Logger

from PageObject.login_page import LoginPage
from PageObject.to_transaction import ToTransaction
# from PageObject.to_left_three import ToLeftThree
from PageObjectRequests.to_left_three import ToLeftThree
# from PageObject.check_material_year_and_status import CheckMaterialYearAndStatus
from PageObjectRequests.check_material_year_and_status import CheckMaterialYearAndStatus
from util.inform.sendEmail import sendEmail
from util.inform.sendNote import AliyunSMS
from pdfSplitWithRedis import get_pdf_and_split
from util.redis_manage_file import redisManageFile

# from writeMethod.write_method import write, write_portion
from test_write_method import write, write_portion
# from test.test_write_method import write, write_portion

from util.g import g
from settings import chrome_driver_path, start_url, materials_path, log_path, site_type, web_type, IncludeProvinceSiteArea


# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #  use ``` chrome.exe --remote-debugging-port=9222 --user-data-dir="C:\selenum\AutomationProfile" ``` this to open debug brower  in port 9222
# c_username='91110108MA01EMR49Y', c_userpwd='Hz123456'

# # 国网 或省网断网中 暂时无法上传


def check_and_send(status=None, is_check=False):
    if not status:
        status = DbTools.get_entresstatus_by_co_id(co_id=g.co_id, year=g.year)
    record = hzflowOperation.get_log(co_id=status.get("co_id"), year=status.get("year"))
    # 处理撤回状态
    if not is_check:
        handle_revert_status(status, record)

    process = hzflowOperation.checkProcess(g.co_id, g.year)
    if process is True and status.get("c_syncstatus") != 1:
        status["c_syncstatus"] = 1
        res = {"c_syncstatus": 1}
        DbTools.update_entrestatus_fields(res, co_id=g.co_id, year=g.year)
    if process is False or status.get("c_syncstatus") != 1:
        return
    if status and process:
        if int(status.get("c_end_sms")) == 0:
            # 手机号 原来是 status.get("phone")
            AliyunSMS().send_single(
                phone="18305175459,18252095207,18168010465,13182913590", template="SMS_193244862",
                params={"resinfo": "{},国网填报材料上传完成".format(status.get("entname"))},
                fb_time=status.get("fb_time"), res_code=web_type)
            a = {"c_end_sms": 1}
            DbTools.update_entrestatus_fields(map=a, co_id=g.co_id, year=g.year)
        if status.get("p_syncstatus") == 1 and status.get("ul_status") == 1:
            DbTools.update_entrestatus_fields(map={"ul_status": 2}, co_id=g.co_id, year=g.year)

            a = sendEmail(subject="autoflow", content="{} 高企认定材料上传完成".format(g.co_id))
            a.content = "{} 高企认定材料上传完成".format(g.co_id)
            a.send_mail()

def handle_revert_status(status, record):
    # 处理撤回状态
    fb_status = status.get("fb_status")
    fb_time = status.get("fb_time")
    if record is not None:
        process = hzflowOperation.checkProcess(co_id=g.co_id, year=g.year)
        g.withdrow = False
        if fb_status == 2 or fb_status == 0:
            if fb_time != record.fb_time:
                g.withdrow = True
                return False
            if fb_time != record.withdrow_time:
                # # 更新本地 撤回次数
                hzflowOperation.update_field(record, "withdrow_time", fb_time)
                # # 删除附件
                if g.need_file and record.is_compress == 1:
                    ent_material_path = BM.get_material_path()
                    if os.path.exists(ent_material_path):
                        BM.remove_dir(dir=ent_material_path)
                # # 将登陆状态和短信发送状态清空
                hzflowOperation.emptyLoginSmsStatus(co_id=g.co_id, year=g.year)
                # # 清空本地状态信息
                hzflowOperation.emptyProcess(record=record)
                g.record = hzflowOperation.get_log(co_id=g.co_id, year=g.year)
                # 将 flag 置为 false 重新上传材料
                flag = False
                g.withdrow = True
                return False
        if status.get("c_syncstatus") == 1 and process:
            hzflowOperation.update_host_process(record, "")
            check_and_send(status=status, is_check=True)
            return True

def start(ent_res_status=None):

    # 给 g.is_test 赋值
    g.is_test = validate_test

    g.co_id = ent_res_status.get("co_id")
    # 将日志文件命名为 log_co_id
    g.logger = Logger(log_file_name=log_path.replace("log.txt", "log_{}.log".format(g.co_id)), log_level=Logger.DEBUG,
                      logger_name="autoflow_{}".format(web_type)).get_log()
    # 获取当前年份
    g.year = BM.get_current_year()
    # 新增上传状态记录
    record, flag = hzflowOperation.add_log(co_id=g.co_id, year=g.year)
    status = ent_res_status
    g.status = status
    g.entname = status.get("entname")

    # 处理附件状态
    file_stat = status.get("file_stat")
    li = {i.split(":")[0]: i.split(":")[1] for i in file_stat.split(",")}
    g.need_file = True
    if li.get("disable") == '1':
        g.need_file = False
    else:
        if li.get("ctp") == '0':
            g.need_file = False

    host = BM.get_host()
    if record is not None:
        mark_info = record.mark_info
        if not mark_info or mark_info == host:
            if not mark_info and g.mark_num >= g.max_mark:
                g.logger.info("当前ip({})超过最大标记数量:{}".format(host, g.max_mark))
                return True
            hzflowOperation.update_host_process(record, BM.get_host())
        else:
            return True
    else:
        if g.mark_num > g.max_mark:
            g.logger.info("当前ip({})超过最大标记数量:{}".format(host, g.max_mark))
            return True

    # 判断企业附件是否拆分完成 没有完成则等待附件拆分
    if g.need_file is True:
        is_split = DbTools.get_ent_files_completed(co_id=g.co_id, year=g.year)
        if is_split is False:
            g.logger.info("等待附件拆分: {}-{}".format(g.co_id, g.entname))
            return True

    # 处理撤回状态
    revert = handle_revert_status(status, record)
    if revert is True:
        return True

    # 压缩附件
    value = BM.get_file_operate(status=status, operate="split")
    g.status = status
    if g.need_file is True:
        try:
            # 当没有该企业的材料目录，且企业需要材料时 将拆分信息存入 redis
            # if not os.path.exists(ent_material_path) and g.need_file is True:
            list_value = json.dumps(value)
            count = redisManageFile().list_put(list_key=BM.get_host(), list_value=list_value)
            g.logger.info("redis count: {} value: {}".format(count, value))
        except redisManageFile.error as err:
            g.logger.error("连接redis 错误, err:{}".format(err))
            p_split = Process(target=get_pdf_and_split, args=(json.dumps(value),))
            p_split.start()
    # 判断附件压缩完成后再上传材料
    if g.need_file:
        is_compress = DbTools.get_flow_compress(co_id=g.co_id, year=g.year)
        if not is_compress:
            g.logger.info("等待附件压缩: {}-{}".format(g.co_id, g.entname))
            return True


    # TODO 根据 status_records 中的 co_id 查询企业国网账号信息
    # TODO 通过 co_id 查看 材料状态， 附件状态和是否需要上传附件  查看企业材料是否撤回 若材料撤回， 则将材料进度清空，并删除材料，然后重新上传材料
    # 若材料状态没有上传完成 则跳过该企业 附件状态 存入 g 中，若不需要上传材料 上传附件时直接 return
    # status = DbTools.get_entresstatus_by_co_id(co_id=g.co_id, year=g.year)


    print(ent_res_status)
    g.logger.info("{} --- withdrow: {}".format(g.co_id, g.withdrow))
    g.logger.info("{} --- need_file: {}".format(g.co_id, g.need_file))

    if record is not None:
        mark_info = record.mark_info
        if mark_info == BM.get_host():
            pass
        elif mark_info == "" or mark_info is None:
            hzflowOperation.update_field_by_co_id(co_id=g.co_id, year=g.year, field_name="mark_info",
                                                  field_value=BM.get_host())
        else:
            return True
    else:
        hzflowOperation.update_field_by_co_id(co_id=g.co_id, year=g.year, field_name="mark_info",
                                              field_value=BM.get_host())

    c_username = status.get("c_username")
    c_userpwd = status.get("c_userpwd")

    g.record = record
    # c_username = "91320411MA20201Y6Q"
    # c_userpwd = "Hz123456~"
    # # 实例化 谷歌启动项对象。
    option = ChromeOptions()
    # # # 添加该参数使程序不被浏览器检测到自动化工具。
    option.add_experimental_option('excludeSwitches', ['enable-automation'])
    option.add_argument("--ignore-certificate-errors")

    # option.add_argument("--headless")
    # option.add_argument("--no-sandbox")
    # option.add_argument("--disable-dev-shm-usage")
    # option.add_argument("--disable-gpu")
    # option.add_argument("--disable-features=NetworkService")
    # option.add_argument("--window-size=1920x1080")
    # option.add_argument("--disable-features=VizDisplayCompositor")

    # option.add_experimental_option("--headless")
    desired_capabilities = DesiredCapabilities.CHROME
    desired_capabilities["pageLoadStrategy"] = "none"
    driver = webdriver.Chrome(executable_path=chrome_driver_path, options=option)
    driver.maximize_window()
    # 打开登录页面
    driver.get(start_url)
    driver.refresh()
    driver.implicitly_wait(30)

    # 登录
    result = LoginPage(driver).login(c_username=c_username, c_userpwd=c_userpwd)
    # if result is True:
    #     return True
    # TODO 发送短信之前  国网需要看 企业所在区划是否有省网
    province_dict = DbTools.get_area_code_by_co_id(co_id=g.co_id, year=g.year)
    province_code = province_dict.get("province")
    datalog_records = hzflowOperation.get_logs(co_id=g.co_id, year=g.year)
    #  测试时不发短信
    if province_code in IncludeProvinceSiteArea:
        if result is True:
            # 根据 login_status 组合 短信内容
            buffer = list()
            for data in datalog_records:
                if data.login_status == -1:
                    if data.web_type == "ctp":
                        buffer.append("国网")
                    else:
                        buffer.append("省网")
            AliyunSMS().send_single(
                phone=status.get("phone"), template="SMS_193244862",
                params={"resinfo": "{},{}账号或密码错误".format(status.get("entname"), "或".join(buffer))},
                fb_time=status.get("fb_time"), res_code=web_type)
            return True
        else:
            hzflowOperation.emptyLoginSmsStatus(co_id=g.co_id, year=g.year, condition={"sms_status": -1})
    else:
        a = sendEmail(subject="autoflow_ctp_{}".format(g.co_id), content="")
        a.content = "{} 需要确认是否包含省网 区划代码为： {}".format(status.get("entname"), province_code)
        if not test:
            g.logger.info(a.content)
            a.send_mail()

    if not os.path.exists(materials_path):
        os.mkdir(materials_path)

    # 1-上传中、2-上传已完成。-1-国网帐号不正确、-2-省网帐号不正确。-3-国网或 省网断网中，暂时无法上传。
    # TODO 登陆之后 修改 ul_status -> 1
    # if status.get("c_start_sms") == 0:
    #     AliyunSMS().send_single(phone=status.get("phone"), template="SMS_192820696",
    #                             params={"resinfo": "{}, 国网填报材料开始上传,上传过程中请勿登录国网,上传结束后会有短信通知".format(
    #                                 status.get("entname"), "或".join(buffer))}, changed_status=1)
    res = {"ul_status": 1, "c_start_sms": 1}
    if status.get("ul_status") == -2:
        del res["ul_status"]
    DbTools.update_entrestatus_fields(res, co_id=g.co_id, year=g.year)
    # TODO 将附件信息存入 redis 中   description 国网为 0  省网为 1
    # ent_material_path = BM.get_material_path()
    # value = {"biz_code": status.get("stat_id"), "co_id": g.co_id, "file_path": ent_material_path, "description": "0", "operate": "split"}
    # value = BM.get_file_operate(status=status, operate="split")
    # g.status = status
    # if g.need_file is True:
    #     try:
    #         # 当没有该企业的材料目录，且企业需要材料时 将拆分信息存入 redis
    #         # if not os.path.exists(ent_material_path) and g.need_file is True:
    #         list_value = json.dumps(value)
    #         count = redisManageFile().list_put(list_key=BM.get_host(), list_value=list_value)
    #         g.logger.info("redis count: {} value: {}".format(count, value))
    #     except redisManageFile.error as err:
    #         g.logger.error("连接redis 错误, err:{}".format(err))
    #         p_split = Process(target=get_pdf_and_split, args=(json.dumps(value),))
    #         p_split.start()

    # 给企业发送 开始上传材料的邮件 g.status.get("phone")  "18235693860"
    if test is not True:
        a = sendEmail(subject="autoflow", content="{} {} 材料正在上传，在收到材料上传完成信息前请务必不要登录国网或省网查看，以免信息出错。".format(g.co_id, status.get("entname")))
        a.send_mail()
        # note_flag = AliyunSMS().send_single(phone="18235693860",
        #                                     params={"resinfo": "{},材料正在上传，在收到材料上传完成信息前请务必不要登录国网或省网查看，以免信息出错。".format(
        #                                         status.get("entname"))}, changed_status=1)
        # if note_flag is True:
        #     hzflowOperation.update_host_process(record, "")
        #     driver.quit()
        #     g.logger.error("短信发送失败。")
        #     return True

    # 点击我要办理
    to_res = ToTransaction(driver, status=status).to_transaction()
    if to_res is True:
        return True

    if record:
        g.is_first_entry = False if record.first_entry_delete == 1 else True

    # # #  点击左边第三个按钮
    to_write = ToLeftThree(driver, status=status).to_left_three()
    if to_write is True:
        return True

    res = CheckMaterialYearAndStatus(driver).check_material_year_and_status()
    if res is True:
        data = DbTools.get_entresstatus_by_co_id(co_id=g.co_id, year=g.year)
        c_syncstatus = data.get("c_syncstatus")
        p_syncstatus = data.get("p_syncstatus")
        if (c_syncstatus == 3 or c_syncstatus == 4) and (p_syncstatus == 1 or p_syncstatus == 3):
            a = {"ul_status": 2}
            DbTools.update_entrestatus_fields(map=a, co_id=g.co_id, year=g.year)
        return True
    # if record is None:
    #     record = hzflowOperation.add_log_after_delete_record(co_id=g.co_id, year=g.year)
    #     g.record = record

    if flag == False:
        g.repetition = False
        write(driver)

    else:
        g.repetition = True
        # 部分材料填写
        write_portion(driver=driver, record=record)
    if driver:
        driver.quit()
    process = hzflowOperation.checkProcess(co_id=g.co_id, year=g.year)
    if process is True:
        g.logger.info("材料上传完成")
        a = sendEmail(subject="autoflow", content="{} 国网 高企认定材料上传完成".format(g.co_id))
        a.send_mail()
        # TODO 当所有进度已完成后 更新 ent_res_status 中的 c_syncstatus 为 1
        DbTools.update_entrestatus_fields(map={"c_syncstatus": 1}, co_id=g.co_id, year=g.year)

        res_status = DbTools.get_entresstatus_by_co_id(co_id=g.co_id, year=g.year)
        # TODO 检查 ent_res_status 中的 c_syncstatus 为 1 时，修改ul_status -> 2
        if res_status.get("c_syncstatus") == 1 and res_status.get("ul_status") in (0, 1, -2):
            # TODO 给用户发短信提示 材料上传完成
            check_and_send(status=res_status)

# ----------读取配置文件开始
def to_bool(s:str):
    a = s.lower()
    if a in ["true", "yes", "t", "1"]:
        return True
    elif a in ["false", "no", "f", "0", ""]:
        return False


from configparser import ConfigParser

cfg = ConfigParser()
cfg.read("{}\\config.ini".format(base_path))
test_str = cfg.get("runtime", "test")
# validate_test 为 true 时 手动输入验证码 为 False 时 自动识别验证码
validate_str = cfg.get("runtime", "validate_test")
validate_test = to_bool(s=validate_str)
test = to_bool(s=test_str)
test = True
# ----------读取配置文件结束


# class myNewProcess(Process):
class myNewProcess():

    def __call__(self, *args, **kwargs):
        self.run()

    def run(self):
        g.year = BM.get_current_year()
        status_records = DbTools.get_list(year=g.year, status=2, test=test, co_ids=[307566])
        print([i.get("entname") for i in status_records])
        # status_records = DbTools.get_list(year=g.year, status=2, test=test, co_ids=[790647])
        test_list = DbTools.get_all_test()
        print("size: ", len(status_records))
        num = 0
        while num < len(status_records):
            res_status = status_records[num]
            if res_status.get("ul_status") == -1 or res_status.get("c_syncstatus") == 3 \
                    or res_status.get("c_syncstatus") == 4:
                num += 1
                continue
            if not test:
                if res_status.get("co_id") in test_list:
                    num += 1
                    continue
                flag = start(ent_res_status=res_status)
                pro = hzflowOperation.checkProcess(g.co_id, g.year)
                if pro:
                    check_and_send()
                num += 1
                if flag is True:
                    continue
            else:
                # if res_status.get("co_id") in [188535, 307566, 29330, 632294, 966564]:
                flag = start(ent_res_status=res_status)
                num += 1
                if flag is True:
                    continue


if __name__ == '__main__':

    p = myNewProcess()
    p()
    # g.co_id = 307566
    # g.year = 2021
    # check_and_send()
    # AliyunSMS().send_single(
    #     phone="18235693860", template="SMS_193244862",
    #     params={"resinfo": "{},国网填报材料上传完成".format("常州瀚中")},
    #     fb_time=40, res_code=web_type)

